home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Appls / test / magic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-14  |  4.4 KB  |  269 lines  |  [TEXT/????]

  1. /* Magic -- tool to help editing magic squares */
  2.  
  3. #include "stdwin.h"
  4.  
  5. /* Arbitrary limitations */
  6. #define MAXSIZE 25
  7. #define DEFSIZE 5
  8. #define FARAWAY 10000
  9.  
  10. /* Defining data */
  11. int size;
  12. char sq[MAXSIZE][MAXSIZE];
  13.  
  14. /* Derived data */
  15. int rowsum[MAXSIZE];
  16. int colsum[MAXSIZE];
  17. int diagsum, secdiagsum;
  18. int ok;
  19.  
  20. /* Input parameters */
  21. int last;
  22.  
  23. /* Output parameters */
  24. WINDOW *win;
  25. int origleft, origtop;
  26. int rowheight, colwidth;
  27.  
  28. evaluate()
  29. {
  30.     int row, col;
  31.     int sum;
  32.     
  33.     diagsum = 0;
  34.     secdiagsum = 0;
  35.     for (row = 0; row < size; ++row) {
  36.         diagsum += sq[row][row];
  37.         secdiagsum += sq[row][size-1-row];
  38.     }
  39.     
  40.     ok = (diagsum == secdiagsum) && (diagsum > 0);
  41.     
  42.     for (row = 0; row < size; ++row) {
  43.         sum = 0;
  44.         for (col = 0; col < size; ++col)
  45.             sum += sq[row][col];
  46.         rowsum[row] = sum;
  47.         if (ok)
  48.             ok = (sum == diagsum);
  49.     }
  50.     
  51.     for (col = 0; col < size; ++col) {
  52.         sum = 0;
  53.         for (row = 0; row < size; ++row)
  54.             sum += sq[row][col];
  55.         colsum[col] = sum;
  56.         if (ok)
  57.             ok = (sum == diagsum);
  58.     }
  59. }
  60.  
  61. center(h, v, n)
  62.     int h, v;
  63.     int n;
  64. {
  65.     char buf[25];
  66.     int width;
  67.     
  68.     if (n == 0)
  69.         return;
  70.     sprintf(buf, "%d", n);
  71.     width = wtextwidth(buf, -1);
  72.     wdrawtext(h + (colwidth - width)/2, v + wlineheight()/2, buf, -1);
  73. }
  74.  
  75. void
  76. drawproc(win, left, top, right, bottom)
  77.     WINDOW *win;
  78. {
  79.     int h, v;
  80.     int row, col;
  81.     
  82.     v = origtop;
  83.     for (row = 0; row < size; ++row) {
  84.         h = origleft;
  85.         wdrawline(h, v, h+size*colwidth, v);
  86.         for (col = 0; col < size; ++col) {
  87.             center(h, v, sq[row][col]);
  88.             h += colwidth;
  89.         }
  90.         center(h+3, v, rowsum[row]);
  91.         v += rowheight;
  92.     }
  93.     wdrawline(origleft, v, origleft + size*colwidth, v);
  94.     
  95.     center(origleft - colwidth, v, secdiagsum);
  96.     
  97.     h = origleft;
  98.     for (col = 0; col < size; ++col) {
  99.         wdrawline(h, origtop, h, v);
  100.         center(h, v, colsum[col]);
  101.         h += colwidth;
  102.     }
  103.     wdrawline(h, origtop, h, v);
  104.     
  105.     center(h+3, v, diagsum);
  106.     
  107.     wdrawbox(origleft-1, origtop-1, h+2, v+2);
  108.     
  109.     if (last > 0 && ok)
  110.         wdrawbox(origleft-3, origtop-3, h+4, v+4);
  111. }
  112.  
  113. reset(newsize)
  114.     int newsize;
  115. {
  116.     int row, col;
  117.     char buf[100];
  118.     
  119.     size = newsize;
  120.     for (row = 0; row < size; ++row)
  121.         for (col = 0; col < size; ++col)
  122.             sq[row][col] = 0;
  123.     
  124.     evaluate();
  125.     
  126.     last = 0;
  127.     
  128.     sprintf(buf, "%dx%d Magic Square", size, size);
  129.     wsettitle(win, buf);
  130.     
  131.     wsetdocsize(win,
  132.             origleft + (size+1)*colwidth + 3,
  133.             origtop + (size+1)*rowheight);
  134.     
  135.     wchange(win, 0, 0, FARAWAY, FARAWAY);
  136. }
  137.  
  138. init()
  139. {
  140.     colwidth = wtextwidth(" 000 ", -1);
  141.     rowheight = wlineheight() * 2;
  142.     origleft = colwidth;
  143.     origtop = rowheight;
  144. }
  145.  
  146. click(h, v)
  147.     int h, v;
  148. {
  149.     int row, col;
  150.     int oldok;
  151.     
  152.     if (last >= size*size) {
  153.         wfleep();
  154.         return;
  155.     }
  156.     
  157.     if (h < origleft || v < origtop)
  158.         return;
  159.     
  160.     col = (h - origleft) / colwidth;
  161.     row = (v - origtop) / rowheight;
  162.     if (row >= size || col >= size)
  163.         return;
  164.     
  165.     if (sq[row][col] != 0) {
  166.         wfleep();
  167.         return;
  168.     }
  169.     
  170.     sq[row][col] = ++last;
  171.     
  172.     oldok = ok;
  173.     evaluate();
  174.     if (ok != oldok)
  175.         wchange(win, 0, 0, FARAWAY, FARAWAY);
  176.     else
  177.         change(row, col);
  178. }
  179.  
  180. change(row, col)
  181.     int row, col;
  182. {
  183.     wchange(win,
  184.         origleft + col*colwidth + 1, origtop + row*rowheight + 1,
  185.         origleft + (col+1)*colwidth, origtop + (row+1)*rowheight);
  186.     wchange(win, 0, origtop + size*rowheight + 2, FARAWAY, FARAWAY);
  187.     wchange(win, origleft + size*colwidth + 2, 0, FARAWAY, FARAWAY);
  188. }
  189.  
  190. undo()
  191. {
  192.     int row, col;
  193.     int oldok;
  194.     
  195.     if (last == 0) {
  196.         wfleep();
  197.         return;
  198.     }
  199.     
  200.     for (row = 0; row < size; ++row) {
  201.         for (col = 0; col < size; ++col) {
  202.             if (sq[row][col] == last) {
  203.                 sq[row][col] = 0;
  204.                 --last;
  205.                 oldok = ok;
  206.                 evaluate();
  207.                 if (ok != oldok)
  208.                     wchange(win, 0, 0, FARAWAY, FARAWAY);
  209.                 else
  210.                     change(row, col);
  211.                 return;
  212.             }
  213.         }
  214.     }
  215.     /* Shouldn't get here */
  216.     wfleep(); wfleep();
  217. }
  218.  
  219. main(argc, argv)
  220.     int argc;
  221.     char **argv;
  222. {
  223.     EVENT e;
  224.     
  225.     winitargs(&argc, &argv);
  226.     init();
  227.     wsetdefwinsize(origleft + (DEFSIZE+2)*colwidth,
  228.             origtop + (DEFSIZE+2)*rowheight);
  229.     win = wopen("Magic Square", drawproc);
  230.     reset(DEFSIZE);
  231.     
  232.     for (;;) {
  233.         wgetevent(&e);
  234.         switch (e.type) {
  235.         case WE_MOUSE_UP:
  236.             click(e.u.where.h, e.u.where.v);
  237.             break;
  238.         case WE_COMMAND:
  239.             switch (e.u.command) {
  240.             case WC_CLOSE:
  241.                 wdone();
  242.                 exit(0);
  243.             case WC_CANCEL:
  244.                 reset(size);
  245.                 break;
  246.             case WC_BACKSPACE:
  247.                 undo();
  248.                 break;
  249.             }
  250.             break;
  251.         case WE_CLOSE:
  252.             wdone();
  253.             exit(0);
  254.         case WE_CHAR:
  255.             if (e.u.character >= '1' && e.u.character <= '9')
  256.                 reset(e.u.character - '0');
  257.             else if (e.u.character == '0')
  258.                 reset(size);
  259.             else if (e.u.character == 'q') {
  260.                 wdone();
  261.                 exit(0);
  262.             }
  263.             else
  264.                 wfleep();
  265.             break;
  266.         }
  267.     }
  268. }
  269.